﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;

namespace Casamiel.Common.Utilities
{
    
        public sealed class DatetimeUtil
        {
            /// <summary>
            /// 检查时间戳是否有效，过期返回true，否则返回false
            /// </summary>
            /// <param name="timeStamp">时间戳</param>
            /// <param name="expireTime">过期时间，单位：秒</param>
            /// <param name="precision"></param>
            /// <returns></returns>
            public static bool CheckTimeStamp(long timeStamp, int expireTime, TimePrecision precision = TimePrecision.Second)
            {
                long currentUnixTime = GetCurrentUnixTime(precision);
                long num2 = currentUnixTime - timeStamp;
                switch (precision)
                {
                    case TimePrecision.Microsecond:
                        expireTime = (expireTime * 0x3e8) * 0x2710;
                        break;

                    case TimePrecision.Millisecond:
                        expireTime *= 0x3e8;
                        break;
                }
                Console.WriteLine(string.Format("currentTimeStamp:{0}->timeStamp:{1}", currentUnixTime, timeStamp));
                Console.WriteLine(string.Format("timeSpan:{0}->expireTime:{1}", num2, expireTime));
                return (num2 > expireTime);
            }

            /// <summary>
            /// 检查时间戳是否有效，过期返回true，否则返回false
            /// </summary>
            /// <param name="timeStamp">时间戳</param>
            /// <param name="expireTime">过期时间，单位：秒</param>
            /// <param name="precision"></param>
            /// <returns></returns>
            public static bool CheckTimeStamp(string timeStamp, int expireTime, TimePrecision precision = TimePrecision.Second)
            {
                long result = 0L;
                if (!long.TryParse(timeStamp, out result))
                {
                    throw new ArgumentException(string.Format("无效的参数值，timeStamp：{0}", timeStamp));
                }
                return CheckTimeStamp(result, expireTime, precision);
            }

            /// <summary>
            /// 获取当前日期所属月份第一天的开始时间，比如：2014-01-01 00:00:00
            /// </summary>
            /// <param name="dt"></param>
            /// <returns></returns>
            public static DateTime GetBeginTimeForMonth(DateTime dt)
            {
                CheckUtil.ArgumentNotNull(dt, "dt");
                return DateTime.Parse(dt.ToString("yyyy-MM-01"));
            }

            /// <summary>
            /// 当前系统时间转换为Unix时间戳
            /// </summary>
            /// <param name="precision">时间精度，默认精确到秒</param>
            /// <returns>Unix时间戳</returns>
            public static long GetCurrentUnixTime(TimePrecision precision = TimePrecision.Second)
            {
                return GetUnixTime(DateTime.Now, precision);
            }

            /// <summary>
            /// 获取当前日期所属月份最后一天的结束时间，比如：2014-01-31 23:59:59 9999999
            /// </summary>
            /// <param name="dt"></param>
            /// <returns></returns>
            public static DateTime GetEndTimeForMonth(DateTime dt)
            {
                CheckUtil.ArgumentNotNull(dt, "dt");
                return GetFirstDay(dt).AddMonths(1).AddTicks(-1L);
            }

            /// <summary>
            /// 获取当前日期所属月份的第一天，比如：2014-01-01 00:00:00
            /// </summary>
            /// <param name="dt"></param>
            /// <returns></returns>
            public static DateTime GetFirstDay(DateTime dt)
            {
                CheckUtil.ArgumentNotNull(dt, "dt");
                return DateTime.Parse(dt.ToString("yyyy-MM-01"));
            }

        /// <summary>
        /// Unix时间戳转换为系统时间
        /// </summary>
        /// <param name="unixTime">Unix时间戳</param>
        /// <param name="precision"></param>
        /// <returns></returns>
        public static DateTime GetFromUnixTime(long unixTime, TimePrecision precision = TimePrecision.Second)
        {
            DateTime time = TimeZoneInfo.ConvertTime(new DateTime(0x7b2, 1, 1), TimeZoneInfo.Local).AddHours(8);
            string str = "0000000";
            switch (precision)
            {
                case TimePrecision.Microsecond:
                    str = string.Empty;
                    break;

                case TimePrecision.Millisecond:
                    str = "0000";
                    break;

                case TimePrecision.Second:
                    str = "0000000";
                    break;

                default:
                    str = "0000000";
                    break;
            }
            long ticks = long.Parse(unixTime + str);
            TimeSpan span = new TimeSpan(ticks);
            return time.Add(span);
        }

        /// <summary>
        /// 获取当前日期所属月份的最后一天，比如：2014-01-31 00:00:00
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DateTime GetLastDay(DateTime dt)
            {
                CheckUtil.ArgumentNotNull(dt, "dt");
                return GetFirstDay(dt).AddMonths(1).AddDays(-1.0);
            }


            public int ConvertDateTimeInt(System.DateTime time)
            {
            DateTime startTime = TimeZoneInfo.ConvertTime(new DateTime(0x7b2, 1, 1), TimeZoneInfo.Local);//等价的建议1));
            return (int)(time - startTime).TotalSeconds;
            }
            /// <summary>
            /// 系统时间转换为Unix时间戳，默认精确到秒
            /// </summary>
            /// <param name="dt">时间</param>
            /// <param name="precision">时间精度，默认精确到秒</param>
            /// <returns>Unix时间戳</returns>
            public static long GetUnixTime(DateTime dt, TimePrecision precision = TimePrecision.Second)
            {
                //DateTime time = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(0x7b2, 1, 1));
                //DateTime time= TimeZoneInfo.ConvertTime(new DateTime(0x7b2, 1, 1), TimeZoneInfo.Local);//等价的建议写法
            long ticks = (dt.ToUniversalTime().Ticks - 621355968000000000);
                string str = ticks.ToString();
                switch (precision)
                {
                    case TimePrecision.Microsecond:
                        return ticks;

                    case TimePrecision.Millisecond:
                    return ticks/10000;

                    case TimePrecision.Second:
                    return ticks/10000000;
                }
                return ticks;
            }

            /// <summary>
            /// 获取指定日期对应的星期中文名，如：星期一，周一
            /// </summary>
            /// <param name="dt"></param>
            /// <param name="prifix">前缀，默认“星期”</param>
            /// <returns></returns>
            public static string GetWeekCNName(DateTime dt, string prifix = "星期")
            {
                switch (dt.DayOfWeek)
                {
                    case DayOfWeek.Sunday:
                        return (prifix + "日");

                    case DayOfWeek.Monday:
                        return (prifix + "一");

                    case DayOfWeek.Tuesday:
                        return (prifix + "二");

                    case DayOfWeek.Wednesday:
                        return (prifix + "三");

                    case DayOfWeek.Thursday:
                        return (prifix + "四");

                    case DayOfWeek.Friday:
                        return (prifix + "五");

                    case DayOfWeek.Saturday:
                        return (prifix + "六");
                }
                return string.Empty;
            }
            public static string DateDiff(DateTime DateTime1, DateTime DateTime2)
            {
                string str = null;
                try
                {
                    TimeSpan span = (TimeSpan)(DateTime2 - DateTime1);
                    if (span.Days >= 1)
                    {
                        return (DateTime1.Month.ToString() + "月" + DateTime1.Day.ToString() + "日");
                    }
                    if (span.Hours > 1)
                    {
                        return (span.Hours.ToString() + "小时前");
                    }
                    str = span.Minutes.ToString() + "分钟前";
                }
                catch
                {
                }
                return str;
            }

            //public static string DateTimeFormat(object obj, string format, bool isFormat)
            //{
            //    string str = string.Empty;
            //    if ((obj == null) || !PageValidate.IsDateTime(obj.ToString()))
            //    {
            //        return str;
            //    }
            //    if (isFormat)
            //    {
            //        return Convert.ToDateTime(obj).ToString(format);
            //    }
            //    return obj.ToString();
            //}

            public static int GetMonthLastDate(int year, int month)
            {
                DateTime time = new DateTime(year, month, new GregorianCalendar().GetDaysInMonth(year, month));
                return time.Day;
            }

            public static string SecondToDateTime(int seconds)
            {
                TimeSpan span = new TimeSpan(0, 0, seconds);
                return string.Format("{0:00}:{1:00}:{2:00}", (int)span.TotalHours, span.Minutes, span.Seconds);
            }

            public static int SecondToMinute(int Second)
            {
                decimal d = Second / 60M;
                return Convert.ToInt32(Math.Ceiling(d));
            }

            public static int TimeToSecond(int hour, int minute, int second)
            {
                TimeSpan span = new TimeSpan(hour, minute, second);
                return (int)span.TotalSeconds;
            }
        }
     
}
